{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Generating an OpenCL kernel by Textual Substitution"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The simplest approach to generating code is to simply substitute snippets of text into an existing code \"template\". This can be done using the C preprocessor, simple string-based search and replace, or other string-value interpolation functionality present in the language. The example below demonstrates the latter case:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "kernel = r\"\"\"\n",
    "    __kernel void {name}({arguments})\n",
    "    {{\n",
    "      int lid = get_local_id(0);\n",
    "      int gsize = get_global_size(0);\n",
    "      int work_group_start = get_local_size(0)*get_group_id(0);\n",
    "      long i;\n",
    "\n",
    "      for (i = work_group_start + lid; i < n; i += gsize)\n",
    "      {{\n",
    "        {operation};\n",
    "      }}\n",
    "    }}\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One slightly unfortunate fact that plays into using Python's `.format()` facility for this purpose is that opening and closing braces must be escaped by doubling them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "    __kernel void scale(float *y, float a, float *x)\n",
      "    {\n",
      "      int lid = get_local_id(0);\n",
      "      int gsize = get_global_size(0);\n",
      "      int work_group_start = get_local_size(0)*get_group_id(0);\n",
      "      long i;\n",
      "\n",
      "      for (i = work_group_start + lid; i < n; i += gsize)\n",
      "      {\n",
      "        y[i] = a*x[i];\n",
      "      }\n",
      "    }\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(kernel.format(\n",
    "    name=\"scale\",\n",
    "    arguments=\"float *y, float a, float *x\",\n",
    "    operation=\"y[i] = a*x[i]\"\n",
    "))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 0
}